﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TrelloNet;

namespace SprintBoardMaker.Data
{
    public class MockTrelloAccess : ITrelloAccess
    {
        private static MockTrelloAccess _instance;
        public static MockTrelloAccess Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new MockTrelloAccess();
                    _instance.UsersBoards = _instance.GetBoardsForCurrentUser(BoardFilter.Open);
                }
                return _instance;
            }
        }

        public List<NormalizedBoard> UsersBoards { get; set; }

        public MockTrelloAccess()
        {
            ////BoardTitles = this.GetBoardsForUser("123", "ABC", BoardFilter.Open).Select<Board, string>(board => board.Name).ToList<string>();
            //UsersBoards = this.GetBoardsForUser("123", "ABC", BoardFilter.Open);
        }

        /* *********************************** */

        private string _authKey = "FixedAuthID";
        private string _roydanOrgID = "FixedRoydanOrgID";

        public string GetTrelloAPIKey()
        {
            return "FixedTrelloAPIKey" + new Guid().ToString().Replace("-", "").Substring(0, 15);
        }

        public string GetTrelloAuthID()
        {
            return _authKey;
        }

        public string GetRoydanOrgID()
        {
            return _roydanOrgID;
        }

        public void SetRoydanOrgID(string roydanOrgID)
        {
            _roydanOrgID = roydanOrgID;
        }

        //public string AuthenticateUser();
        public void SaveAuthKey(string authKey)
        {
            _authKey = authKey;
        }

        public List<NormalizedBoard> GetBoardsForCurrentUser(BoardFilter filter)
        {
            Board b1 = new Board();
            b1.Closed = GetBoardClosedStatusBasedOnFilter(filter);
            b1.Desc = "Test Board 1 Desc";
            b1.IdOrganization = _roydanOrgID;
            b1.Id = "TestBoard1ID";
            b1.LabelNames = GenerateLabelsForBoard(1);
            b1.Name = "Test Board 1 Name";
            NormalizedBoard nb1 = new NormalizedBoard(b1);

            Board b2 = new Board();
            b2.Closed = GetBoardClosedStatusBasedOnFilter(filter);
            b2.Desc = "Test Board 2 Desc";
            b2.IdOrganization = _roydanOrgID;
            b2.Id = "TestBoard2ID";
            b2.LabelNames = GenerateLabelsForBoard(2);
            b2.Name = "Test Board 2 Name";
            NormalizedBoard nb2 = new NormalizedBoard(b2);

            Board b3 = new Board();
            b3.Closed = GetBoardClosedStatusBasedOnFilter(filter);
            b3.Desc = "Test Board 3 Desc";
            b3.IdOrganization = _roydanOrgID;
            b3.Id = "TestBoard3ID";
            b3.LabelNames = GenerateLabelsForBoard(3);
            b3.Name = "Test Board 3 Name";
            NormalizedBoard nb3 = new NormalizedBoard(b3);

            return new List<NormalizedBoard>(new[] { nb1, nb2, nb3 });
            //return new List<Board>(new[] { b1, b2, b3 });
        }

        public List<Member> GetOrgMembers(string orgID)
        {
            List<Member> members = new List<Member>();

            members.Add(new Member() { FullName = "Test User1", Initials = "T1", Username = "tuser1" });
            members.Add(new Member() { FullName = "Test User2", Initials = "T2", Username = "tuser2" });
            members.Add(new Member() { FullName = "Test User3", Initials = "T3", Username = "tuser3" });

            return members;
        }

        //public Dictionary<Color, string> GetBoardLabels(string sBoardID)
        //{
        //    Dictionary<Color, string> dict = new Dictionary<Color, string>();

        //    dict.Add(Color.Blue, "Blue Category"); 
        //    dict.Add(Color.Red, "Red Category");
        //    dict.Add(Color.Green, "Green Category");
        //    dict.Add(Color.Orange, "Orange Category");
        //    dict.Add(Color.Purple, "Purple Category");
        //    dict.Add(Color.Yellow, "Yellow Category");

        //    return dict;
        //}

        public List<TrelloNet.List> GetListsForBoard(string boardID)
        {
            Random randy = new Random(DateTime.Now.Millisecond);
            List<TrelloNet.List> lists = new List<List>();

            TrelloNet.List l1 = new TrelloNet.List();
            l1.Closed = false;
            l1.Pos = 0;
            l1.Name = "List 1: " + randy.Next(1, 100);
            lists.Add(l1);

            TrelloNet.List l2 = new TrelloNet.List();
            l2.Closed = false;
            l2.Pos = 1;
            l2.Name = "List 2: " + randy.Next(1, 100);
            lists.Add(l2);

            int r = randy.Next(1, 2);

            if (r == 2)
            {
                TrelloNet.List l3 = new TrelloNet.List();
                l3.Closed = false;
                l3.Pos = 2;
                l3.Name = "List 3: " + randy.Next(1, 100);
                lists.Add(l3);

                if (randy.Next(1, 2) == 2)
                {
                    TrelloNet.List l4 = new TrelloNet.List();
                    l4.Closed = false;
                    l4.Pos = 3;
                    l4.Name = "List 4: " + randy.Next(65, 100);
                    lists.Add(l4);
                }
            }

            return lists;
        }

        public List<TrelloNet.Member> GetMembersForBoard(string boardID)
        {
            List<TrelloNet.Member> members = new List<Member>();

            TrelloNet.Member m1 = new Member();
            m1.FullName = "User 1";
            m1.Username = "testuser1";
            m1.Initials = "U1";
            members.Add(m1);

            TrelloNet.Member m2 = new Member();
            m2.FullName = "User 2";
            m2.Username = "testuser2";
            m2.Initials = "U2";
            members.Add(m2);

            Thread.Sleep(142);      // Pause of randomly selected length
            Random randy = new Random(DateTime.Now.Millisecond);
            int r = randy.Next();
            if (r % 3 == 0)
            {
                TrelloNet.Member m3 = new Member();
                m3.FullName = "User 3";
                m3.Username = "testuser3";
                m3.Initials = "U3";
                members.Add(m3);

                if (randy.Next() % 2 == 0)
                {
                    TrelloNet.Member m4 = new Member();
                    m4.FullName = "User 4";
                    m4.Username = "testuser4";
                    m4.Initials = "U4";
                    members.Add(m4);
                }
            }

            return members;
        }

        public void CreateBoard(string name, NormalizedBoard boardToCreate)
        {
            TrelloNet.Board boardToAdd = new Board();
            boardToAdd.Closed = false;
            boardToAdd.Desc = name;
            boardToAdd.IdOrganization = boardToCreate.OrganizationID;
            boardToAdd.Name = name;
            boardToAdd.Prefs = boardToCreate.Preferences;

            foreach (var x in boardToCreate.Labels)
            {
                boardToAdd.LabelNames.Add(x.Key, x.Value);
            }
        }

        private bool GetBoardClosedStatusBasedOnFilter(BoardFilter filter)
        {
            if (filter == BoardFilter.Open)
            {
                return (new Random(DateTime.Now.Millisecond).Next(1, 10) % 2) == 0;
            }

            return false;
        }

        private Dictionary<Color, string> GenerateLabelsForBoard(int iBoardNum)
        {
            Random randy = new Random(DateTime.Now.Millisecond);

            Dictionary<Color, string> labels = new Dictionary<Color, string>();

            if (randy.Next() % 3 == 0)
                labels.Add(Color.Blue, "Board " + iBoardNum.ToString() + " Blue Label");
            if (randy.Next() % 5 == 0)
                labels.Add(Color.Red, "Board " + iBoardNum.ToString() + " Red Label");
            if (randy.Next() % 7 == 0)
                labels.Add(Color.Green, "Board " + iBoardNum.ToString() + " Green Label");
            if (randy.Next() % 3 == 0)
                labels.Add(Color.Orange, "Board " + iBoardNum.ToString() + " Orange Label");
            if (randy.Next() % 2 == 0)
                labels.Add(Color.Purple, "Board " + iBoardNum.ToString() + " Purple Label");
            if (randy.Next() % 4 == 0)
                labels.Add(Color.Yellow, "Board " + iBoardNum.ToString() + " Yellow Label");

            return labels;
        }


        public Uri GetAuthorizationURI()
        {
            return new Uri("http://www.google.com");
        }
    }
}
